home *** CD-ROM | disk | FTP | other *** search
- #include "7plus.h"
- #include "globals.h"
-
- /*
- *** encode a file. split, if desired/needed. create correction file.
- ***
- ***
- */
-
- int encode_file (char *name, long blocksize, char *searchbin)
- {
- int part, parts, blockzeilen, lfd_zeile;
- int correct, corrzeilen, corrpart, corrzeile;
- uint csequence;
- ulong danach[16], *dn, h;
- long binbytes, binb0, position, size;
- char destname[13], hdrname[MAXFNAME], filename[13], corrname[13];
- char orgname[66], inpath[MAXFPATH], zeile[81], zeile2[81];
- char dummi[20], dummi2[20], *q, *r;
- FILE *rein, *raus, *corr;
- register i, j, k;
-
- correct = i = 0;
- *destname = *hdrname = *filename = *corrname = *inpath = *orgname = EOS;
- *_file = EOS;
- raus = NULL;
-
-
- if (fls)
- if (!test_exist ("7plus.fls"))
- unlink ("7plus.fls");
-
- if (searchbin)
- {
- /* Get serchpath for binary (original) file. */
- fnsplit (searchbin, _drive, _dir, _file, _ext);
- sprintf (inpath, "%s%s", _drive, _dir);
- }
-
- q = name;
- /* create correction file, if ext of input file is .ERR */
- if ((r = strrchr (q, '.')) != NULL)
- if (!strnicmp (".err", r, 4))
- {
- /* OK, input file is an error file */
- correct = 1;
-
- if (crc_file (q, "7PLUS error", "00\n", 1) == 1)
- return (7);
-
- corr = fopen (q, OPEN_READ_TEXT);
-
- /* Find starting line. */
- while ((r = my_fgets (zeile, 80, corr)) != NULL)
- if (!strncmp (zeile, "7PLUS ", 6))
- break;
- if (!r)
- {
- printf ("\007'%s': invalid error report. Break.\n", q);
- fclose (corr);
- return (7);
- }
- /* Get name, lines per part, and length of original file from error file.*/
- *orgname = EOS;
- binb0 = 0L;
- sscanf (zeile+20, "%12s %s /%66[^/]/ %ld",
- corrname, dummi, orgname, &binb0);
- corrzeilen = get_hex (dummi);
- if (!*orgname)
- {
- binb0 = 0L;
- sscanf (zeile+20, "%s %s %ld", dummi, dummi, &binb0);
- }
- strlwr (corrname);
- if (extended != '*' || !*orgname)
- strcpy (orgname, corrname);
- /* Build complete filename for original file */
- if (!*_file)
- strcat (inpath, orgname);
- else
- {
- strcat (inpath, _file);
- strcat (inpath, _ext);
- }
- q = inpath;
- }
-
- if ((rein = fopen (q, OPEN_READ_BINARY)) == NULL)
- {
- printf ("\007'%s' not found. Break.\n", q);
- return (2);
- }
-
- /* determine size of original file. This could be done with filestat(),
- but it's not available on all compilers. */
- fseek (rein, 0L, SEEK_END); /* position read pointer to end of file. */
- size = ftell (rein); /* get size. */
- fseek (rein, 0L, SEEK_SET); /* reposition to beginning of file. */
-
- if (correct && binb0 && size != binb0)
- {
- printf (notsame, "error report");
- return (15);
- }
-
- part = parts = 1;
-
- if (!correct)
- {
- /* Bufferize input, if we're encoding. */
- setvbuf (rein, NULL, _IOFBF, buflen);
-
- /* if blocksize is greater then try to split into blocksize-50000 parts */
- if (blocksize > 50000L)
- {
- blocksize -= 50000L;
- /* calculate how many assci-bytes per part are needed to get roughly
- equal filelengths. */
- blocksize = (((size + 61) / 62) + (blocksize - 1)) / blocksize;
- blocksize *= 62;
- }
-
- /* if blocksize is defined as zero or if it's bigger than the file,
- set it to filelength */
- if (!blocksize || blocksize > size)
- blocksize = size;
-
- /* automatically split into 512 line parts, if file is bigger. */
- if (blocksize > (512 * 62))
- {
- blocksize = 512 * 62;
- printf ("Blocksize limited to 512 lines per file.\n");
- }
- /* how many lines do the parts contain? */
- blockzeilen = (int) ((blocksize + 61) / 62);
-
- /* how many parts result from that? */
- parts = (int) ((size + blocksize-1) / blocksize);
-
- if (parts > 255)
- {
- printf ("\007Not more than 255 parts allowed.\n");
- printf ("Choose different blocksize. Break.\n");
- return (8);
- }
- }
- /* generate filenames */
- fnsplit (q, NULL, NULL, _file, _ext);
- sprintf (orgname, "%s%s", _file, _ext);
- build_DOS_name (_file);
- build_DOS_name (_ext);
- /* make sure, the name isn't longer than 8 chars
- and extension not longer 4 (including dot). */
- _file[8] = _ext[3] = EOS;
-
- strcpy (destname, _file);
- sprintf (hdrname, "%s%s%s", _file, _ext[0]?".":"", _ext);
- strupr (hdrname);
-
- printf ("\n");
-
- /* encode parts */
- for (part=1; part<parts+1 ; part++)
- {
- if (!correct)
- {
- /* generate output filename. *.7PL, if unsplit. *.PXX if split.
- XX represents a two digit hex number. */
- if (parts == 1)
- {
- sprintf (filename, "%s%s", destname, ".7pl");
- printf ("'%s': Writing.\r", filename);
- }
- else
- {
- sprintf (filename, "%s.p%02x", destname, part);
- printf ("'%s': Writing part %03d of %03d.\r", filename, part, parts);
- }
-
- fflush (stdout);
-
- /* check, if output file already exists. */
- test_file (raus, filename, 0, 12);
- }
- else /* we're creating a correction file, set name accordingly. */
- {
- fnsplit (corrname, NULL, NULL, destname, NULL);
- sprintf (filename, "%s.cor", destname);
- }
- raus = fopen (filename, OPEN_WRITE_TEXT);
- setvbuf (raus, NULL, _IOFBF, buflen);
-
- if (!correct)
- {
- if (part == parts && parts > 1)
- {
- if (size % blocksize)
- blocksize = size % blocksize;
- blocksize = ((blocksize + 61 ) / 62) *62;
- }
- /* output header */
- sprintf (zeile, " go_7+. %03d of %03d %-12s %07ld %04X %03X (7PLUS v1.6) \
- \xb0\xb1\xb2%c", part, parts, hdrname, size,
- (uint)(((blocksize+61)/62) * 64), blockzeilen,
- extended);
-
- mcrc (zeile, 1);
- add_crc2 (zeile);
- fprintf (raus, "%s%s", zeile, delimit);
-
- if (part == 1 && extended == '*')
- {
- sprintf (zeile, "///////////////////////////////////////////////////\
- ///////////\xb0\xb1\xb2*");
- strcpy (zeile+1, orgname);
- zeile[(int)strlen(orgname)+1] = '/';
- mcrc (zeile, 1);
- add_crc2 (zeile);
- fprintf (raus, "%s%s", zeile, delimit);
- }
- }
- else
- {
- /* output correction file header */
- strcpy (dummi2, filename);
- strupr (dummi2);
- fprintf (raus, " go_text. %s%s", dummi2, delimit);
- strupr (corrname);
- fprintf (raus, "7PLUS correction: %s %ld%s", corrname, size, delimit);
- strlwr (corrname);
- fscanf (corr, "%s", dummi2);
- corrpart = get_hex (dummi2);
- fprintf (raus, " P%02x:%s", corrpart, delimit);
- }
-
- lfd_zeile = j = 0;
- binbytes = 0L;
-
- /* get bytes from original file until it ends or blocksize is reached. */
- while (!feof(rein) && ((binbytes < blocksize) || parts == 1))
- {
- csequence = 0;
-
- if (correct)
- {
- /* get number of part and number of line to put into correction file
- from error file */
- fscanf (corr, "%s", dummi2);
- corrzeile = get_hex (dummi2);
- if (corrzeile == 0xfff)
- {
- corrpart = 0;
- fscanf (corr, "%s", dummi2);
- corrpart = get_hex (dummi2);
- if (!corrpart)
- break;
- fprintf (raus, " P%02x:%s", corrpart, delimit);
- fscanf (corr, "%s", dummi2);
- corrzeile = get_hex (dummi2);
- }
- lfd_zeile = corrzeile;
- /* calculate position in original file to get data from. */
- position = (long)(corrpart-1) * 62 * (long)corrzeilen +
- 62 * (long)corrzeile ;
- /* position read pointer. */
- fseek (rein, position, SEEK_SET);
- fprintf (raus, " L%03X:%s", corrzeile, delimit);
- }
-
- /* get two groups of 31 bytes and stuff them into 2 * 8 longs. */
- dn = danach;
- for (i=0; i<2; i++, dn+=8)
- {
- /* Get 31 Bytes and put them into 8 longs. */
- for(j=0; j<8; j++)
- {
- dn[j] = 0L;
- for (k=(j==7)?2:3; k>-1; k--)
- {
- if ((h = fgetc (rein)) == EOF)
- {
- if (!i && !j && k == 3)
- i = 255;
- h = 0L;
- }
- dn[j] = (dn[j] << 8) | h;
- }
- }
- /* Rearrange into 8 31bit values. */
- dn[7] = dn[7] | ((dn[6] & 127L) << 24);
- dn[6] = (dn[6] >> 7) | ((dn[5] & 63L ) << 25);
- dn[5] = (dn[5] >> 6) | ((dn[4] & 31L ) << 26);
- dn[4] = (dn[4] >> 5) | ((dn[3] & 15L ) << 27);
- dn[3] = (dn[3] >> 4) | ((dn[2] & 7L ) << 28);
- dn[2] = (dn[2] >> 3) | ((dn[1] & 3L ) << 29);
- dn[1] = (dn[1] >> 2) | ((dn[0] & 1L ) << 30);
- dn[0] = (dn[0] >> 1);
- }
- /* i is 256, then no bytes were read. End of file. */
- if (i == 256)
- break;
-
- binbytes += 62;
-
- /* write code line to output file. do radix216 conversion, crc
- calculation and ascii conversion as we go along. */
- for (i=j=0;i<16;i++)
- {
- zeile2[j++] = code[(int)(danach[i] % 0xd8L)];
- danach[i] /= 0xd8L;
- zeile2[j++] = code[(int)(danach[i] % 0xd8L)];
- danach[i] /= 0xd8L;
- zeile2[j++] = code[(int)(danach[i] % 0xd8L)];
- zeile2[j++] = code[(int)(danach[i] / 0xd8L)];
- }
-
- for (i=0;i<64;i++)
- csequence = crctab[csequence>>8] ^ (((csequence&255)<<8) |
- (byte) zeile2[i]);
-
- /* package line number and crc into three radix216 bytes and add
- to code line. */
- danach[0] = ((long)(lfd_zeile & 0x1ff) << 14) | (csequence & 0x3fff);
- zeile2[j++] = code[(int) (danach[0] % 0xd8L)];
- danach[0] /= 0xd8L;
- zeile2[j++] = code[(int) (danach[0] % 0xd8L)];
- zeile2[j++] = code[(int) (danach[0] / 0xd8L)];
-
- add_crc2 (zeile2);
- fprintf (raus, "%s", zeile2);
-
- /* conclude line with line separator. */
- fprintf (raus, delimit);
- lfd_zeile++; /* increase line counter. */
- }
-
- if (!correct) /* put end indicator into output file. */
- {
- strupr (filename);
- fprintf (raus, " stop_7+. (%s)%s", filename, delimit);
- }
- else
- {
- /* if we were creating correction file, complete it. */
- fprintf (raus, " P00:%s", delimit);
- fclose (raus);
- crc_file (filename, "7P", " P00:\n", 0);
- raus = fopen (filename, OPEN_APPEND_TEXT);
- fprintf (raus, " stop_text.%s", delimit);
- }
-
- if (endstr)
- fprintf (raus, "%s%s", endstr, delimit);
-
- if (ferror(raus)) /* did any errors occur while writing? */
- {
- printf ("\n\007Write error. Break.\n");
- fclose (rein);
- return (1);
- }
-
- /* OK. This part is done. */
- fclose (raus);
-
- } /* end of for() */
-
- /* all parts done.
- tell user about action. */
- if (correct)
- printf ("\nCorrection file '%s' compiled.\n\n", filename);
- else
- {
- printf ("\n\nEncoding successful!\n\n");
- if (fls)
- {
- if ((raus = fopen ("7plus.fls", OPEN_WRITE_TEXT)) == NULL)
- return (14);
- fnsplit (filename, NULL, NULL, _file, NULL);
- fprintf (raus, "%d %s\n", parts, _file);
- fclose (raus);
- }
- }
- fclose (rein);
- return (0);
- }
-